

#include     <stdio.h>
#include     <stdlib.h> 
#include     <unistd.h>  
#include     <sys/types.h>
#include     <sys/stat.h>
#include     <fcntl.h> 
#include     <termios.h>
#include     <errno.h> 
#include     <string.h>
#include    <arpa/inet.h>
#include    <sys/socket.h>


#include <pthread.h>
#include <limits.h>
#include <signal.h>
#include <sys/ioctl.h>


#include<sys/wait.h>
#include <sys/ipc.h> 
#include <sys/msg.h>


#define DEV_NAME "/dev/ttyS1"
#define DEV_NAME2 "/dev/ttyS2"
int testi=0;

//extern int pthread_create __P ((pthread_t *__thread, __const pthread_attr_t *__attr,
//void *(*__start_routine) (void *), void *__arg));
#define PORT 10071
#define REMOTE_IP "183.60.111.161"
#define MAXBUF 512
char senddate=0;
char send_buf[MAXBUF+1];
char recv_buf[MAXBUF+1];

char breath[10]={"hello"};


// 等待时间  串口描述符  读取的buff
int Select_Tart_Read(struct timeval tv,int  uart_fd,char* buff)
{
    
    memset(buff,0,80);
    fd_set rfds;
    int retval=0;
    int i;
    
    FD_ZERO(&rfds);
    FD_SET(uart_fd, &rfds);
    
    retval=select(uart_fd + 1, &rfds, NULL, NULL, &tv);
  //retval=select(uart_fd + 1, &rfds, NULL, NULL, NULL);
    if(retval<0)
    {  
        perror("select error\n");  
    }
    else
    {  
        if( retval &&   FD_ISSET(uart_fd, &rfds)  )
        {
            testi++;
            printf("FD_ISSET!6\n");
            int rc=read(uart_fd,buff,80);
          
          printf("FD_ISSET!3\n");
            if(rc>0)
            {
                printf("recv serial----rc is %d   testi is %d \n  ",rc,testi);
              //  for(i = 0; i < 80; i++)
              //  printf(" %x ", buff[i]);
              //  printf("\n");
                return rc;
            }
        }    
    }    
    return 0;
}


int monitor_routine( int  uart_fd)
{
    int i;
 //   printf("in  monitor_routine\n");
    
    char rebuff[80];//设置最大的数据长度为8个
    memset(rebuff,0,80);
    struct timeval tv={0,3};
    struct timeval timeout={0,3}; //select等待3微秒，3微秒轮询，要非阻塞就置0
   // tv.tv_sec = 0;
  //  tv.tv_usec = 10000;
    int retval;
  //  unsigned char commbuff[8];//设置最大的数据长度为8个
   // memset(commbuff,0,sizeof(unsigned char)*8);
    
  //  while(1)
    {
        //printf("retval is %d\n",retval);
        if(Select_Tart_Read(tv,uart_fd,rebuff)>0)//
        {
            printf("in while Read!\n");
            for(i = 0; i < 80; i++)
		{
                printf(" %x ", rebuff[i]);
                rebuff[i]=0;
		}
            printf("\n");
        }
    }
    return 0;
}
/////////////////////////////////

int cominit2(void)
{
        int iFd, i;
        int len;
        unsigned char ucBuf[100];
        struct termios opt;

        iFd = open(DEV_NAME2, O_RDWR|O_NOCTTY|O_NDELAY);
              
        if(iFd < 0) {
                perror(DEV_NAME);
                printf(" open /dev/ttyS2 faurel!\n");
                return -1;
        }
        else 
            printf(" open /dev/ttyS2 success!\n");
        tcgetattr(iFd, &opt);
        cfsetispeed(&opt, B115200);
        cfsetospeed(&opt, B115200);

        if (tcgetattr(iFd,   &opt)<0) {
                  return   -1;
        }
        opt.c_lflag    &= ~(ECHO | ICANON | IEXTEN | ISIG);
        opt.c_iflag    &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
        opt.c_oflag     &= ~(OPOST);
        opt.c_cflag     &= ~(CSIZE | PARENB);
        opt.c_cflag     |=  CS8;

        opt.c_cc[VMIN]     = 255;
        opt.c_cc[VTIME]    = 150;

        if (tcsetattr(iFd,   TCSANOW,   &opt)<0) {
                return   -1;
        }
        tcflush(iFd,TCIOFLUSH);
        
        
        for (i = 0; i < 100; i++){
                ucBuf[i] = 0xff - i;
        }
        
        
        char buff[6];
        buff[0]=0x05;buff[1]=0x05;buff[2]=0x05;buff[3]=0x05;buff[4]=0x05;buff[5]=0x05;
        
        
       // printf("buff is :\n");
       // for(i=0;i<6;i++)
         //   printf("0x%x ",buff[i]);
       // printf("\n");
        
       // printf("write buff!!!");
        
        len = write(iFd, buff, 6);
        
        if(len < 0) {
             
            printf(" com2 write error ! \n");
            return -1;
        }
        
        printf("协处理器串口连接成功\n");
        
      //  monitor_routine(iFd);
        
        printf("\n");



       // close(iFd);
        return iFd;
}

//////////////////////////////////

int cominit(void)
{

#if 0
int fd;
    int i;
    int len;
    int n = 0;      
    char read_buf[256];
    char write_buf[256];
    struct termios opt; 
    char count=0;
    fd = open("/dev/ttyS1", O_RDWR|O_NOCTTY|O_NDELAY);
    if(fd == -1)
    {
        perror("open serial 0\n");
        exit(0);
    }

    tcgetattr(fd, &opt);      
	bzero(&opt, sizeof(opt));
    
	tcflush(fd, TCIOFLUSH);

	cfsetispeed(&opt, B115200);
    cfsetospeed(&opt, B115200);
    
    opt.c_cflag &= ~CSIZE;  
    opt.c_cflag |= CS8;   
    opt.c_cflag &= ~CSTOPB; 
    opt.c_cflag &= ~PARENB; 
    opt.c_cflag &= ~CRTSCTS;
    opt.c_cflag |= (CLOCAL | CREAD);
 
    opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
 
    opt.c_oflag &= ~OPOST;
    
    opt.c_cc[VTIME] = 0;
    opt.c_cc[VMIN] = 0;
    
    tcflush(fd, TCIOFLUSH);
 
    printf("configure complete\n");
	
    if(tcsetattr(fd, TCSANOW, &opt) != 0)
    {
        perror("serial error");
        return -1; 
    }

    printf("start send and receive data\n");

	while(1)
    {    
        n = 0;
        len = 0;
        bzero(read_buf, sizeof(read_buf)); 
        bzero(write_buf, sizeof(write_buf));
 
     //   while( (n = read(fd, read_buf, sizeof(read_buf))) > 0 )
n = read(fd, read_buf, sizeof(read_buf));
if(n>0)
{
        {
            for(i = len; i < (len + n); i++)
            {
                write_buf[i] = read_buf[i - len];
            }
            len += n;
        }
        write_buf[len] = '\0';
              
        printf("Len %d \n", len);
        printf("%s \n", write_buf);
        //  if(senddate)
           {


        n = write(fd, write_buf, strlen(write_buf));
           senddate=0;
               bzero(send_buf, sizeof(send_buf)); 
           }
        printf("write %d chars\n",n);
         //  if(len)
       //  send(new_fd, read_buf, strlen(read_buf), 0); //第 4 步 向套接字中写入字符串
       //  else
          {
                count++;
               if(count>30)
                {
             // send(new_fd, breath, strlen(breath), 0); //第 4 步 向套接字中写入字符串
                     count=0;
                      }
              }
}
       // sleep(1);
    }


     return 0;

#else
        int iFd, i;
        int len;
        unsigned char ucBuf[100];
        struct termios opt;

        iFd = open(DEV_NAME, O_RDWR|O_NOCTTY|O_NDELAY);
              
        if(iFd < 0) {
                perror(DEV_NAME);
                printf(" open /dev/ttyS1 faurel!\n");
                return -1;
        }
        else 
            printf(" open /dev/ttyS1 success!\n");
        tcgetattr(iFd, &opt);
        cfsetispeed(&opt, B115200);
        cfsetospeed(&opt, B115200);

        if (tcgetattr(iFd,   &opt)<0) {
                  return   -1;
        }
        opt.c_lflag    &= ~(ECHO | ICANON | IEXTEN | ISIG);
        opt.c_iflag    &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
        opt.c_oflag     &= ~(OPOST);
        opt.c_cflag     &= ~(CSIZE | PARENB);
        opt.c_cflag     |=  CS8;

        opt.c_cc[VMIN]     = 255;
        opt.c_cc[VTIME]    = 150;

        if (tcsetattr(iFd,   TCSANOW,   &opt)<0) {
                return   -1;
        }
        tcflush(iFd,TCIOFLUSH);
        
        
        for (i = 0; i < 100; i++){
                ucBuf[i] = 0xff - i;
        }
        
        
        char buff[6];
        buff[0]=0x05;buff[1]=0x05;buff[2]=0x05;buff[3]=0x05;buff[4]=0x05;buff[5]=0x05;
        
        
     //   printf("buff is :\n");
      //  for(i=0;i<6;i++)
      //      printf("0x%x ",buff[i]);
     //   printf("\n");
        
     //   printf("write buff!!!");
        
        len = write(iFd, buff, 6);
        
        if(len < 0) {
             
            printf(" write error ! \n");
            return -1;
        }
        
        printf("zigbee串口连接成功\n");
        
      //  monitor_routine(iFd);
        
        printf("\n");



       // close(iFd);
        return iFd;
#endif
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
void u_alarm_handler()
{
}
int severinit(void)
{
    int sockfd,comid;
    int i;

     if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0)//第 1 步 创建一个体套接字
           {
         printf("socket err:\n");
         exit(1);
          }
          else
          {
  
            printf("socket id=%d:\n",sockfd);
         }
   struct sockaddr_in svraddr;//第 2 步 设置 addr 结构体
      bzero(&svraddr,sizeof(svraddr));
   svraddr.sin_family=AF_INET;//使用 internet 协议
   svraddr.sin_port=htons(PORT);
   //inet_aton("183.60.111.161",&svraddr.sin_addr);
   svraddr.sin_addr.s_addr=inet_addr(REMOTE_IP);
     i=1;
 
   while(i)
      {


      
   if((connect(sockfd,(struct sockaddr*)&svraddr,sizeof(svraddr)))<0)
          {
           
               //   exit(1);
         
              i++;
             //  if(i>10)
		{
 		printf("failt sockfd=%d:\n",sockfd);
                printf("云服务器连接失败:\n");
                i=0;
		 return -1;
		}
             }
          else
          {

          printf("云服务器连接成功:\n");
           printf("connect ok:\n");
              i=0;
               }
              //第 3 步 连接
              }
   
 return sockfd;
}


//make package/helloworld/compile V=s
//find bin/ -name "helloworld*.ipk"
//假设在package/network/zigbeeservice_test目录下是要编译的代码。
//先make menuconfig
//于pthread库不是Linux系统默认的库，连接时需要使用库libpthread.a,所以在使用pthread_create创建线程时，在编译中要加-lpthread参数:
//找到对应的选项，然后配置该选项为'M'，保存退出
//然后输入make package/network/zigbeeservice_test/compile即可编译出ipk文件。
//mipsel-openwrt-linux-gcc gateway.c  -ldl -lpthread  -o gateway
//mipsel-openwrt-linux-gcc lc_tty.c lc_tty.h main.c -ldl -lpthread -o main

//下面是示例代码：
//代码是服务器TCP模型，采用多路复用的select函数实现了循环的监听并接受客户端的功能，其中也包含了上传下载的功能*/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/socket.h>
#include<string.h>
#include<netinet/in.h>
#include<sys/ioctl.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/types.h>
#include<dirent.h>
 
int main()
{
    struct sockaddr_in seraddr,cliaddr;
    int listenfd,connfd,fd1,fd2,n,m,l,severid,comid,comid2;
    char user[20],buf[4096];
    fd_set  readfds,tmpfds;//岗哨监控集合
    socklen_t addrlen;
    DIR *dr;
    struct dirent *file;
    int port=8080;
  //  printf("请输入需要设定的服务器名称:");
   // scanf("%s",user);
     
  //  printf("请输入需要设定的服务器端口:");
  //  scanf("%d",&port);
  //  getchar();
 
    if((listenfd=socket(AF_INET,SOCK_STREAM,0))<0)
    {
        perror("创建失败");
       exit(-1);
    }
     
     
 
    /*开始设定服务器的参数地址类型,IP,PORT*/
    memset(&seraddr,0,sizeof(seraddr));//将服务器的初值空间清空，防止转化过程有影响
    seraddr.sin_family=AF_INET;
    seraddr.sin_port=htons(port);//将得到的本地端口转换为网络字节序
    seraddr.sin_addr.s_addr=htonl(INADDR_ANY);//将得到的ip地址字符串转换为网络字节序的ip地址数值//IP地址设置成INADDR_ANY,让系统自动获取本机的IP地址。
  	 comid=cominit();
         comid2=cominit2();
  	 severid=severinit();
     
    if((bind(listenfd,(struct sockaddr*)&seraddr,sizeof(seraddr))<0))
    {
        perror("绑定失败");
       exit(-1);
    }
    printf("绑定创建\n");
    if((connfd=listen(listenfd,50))<0)
    {
        perror("监听失败");
        exit(-1);
    }
    printf("开始监听手机直连\n");
    FD_ZERO(&readfds);//初始化文件集
    FD_SET(listenfd,&readfds);//将需要监视的listenfd放入readfds集中
  struct timeval tv={0,3};//select等待3微秒，3微秒轮询，要非阻塞就置0
    while(1)//循环监听
    {
        int nread,n;
        tmpfds=readfds;//将监视集传递给临时的监视集中，防止后续的操作修改了监视集
        if(severid>0)
       monitor_routine(severid);//
       if(comid>0)
       monitor_routine(comid);
 if(comid2>0)
       monitor_routine(comid2);
//if(select(FD_SETSIZE,&tmpfds,NULL,NULL,NULL)<0)//设置监视，监视tmpfds内的子fd变化,发生变化的将会被保留在tmpfds中
          
      if(select(FD_SETSIZE,&tmpfds,NULL,NULL,&tv)<0)//设置监视，监视tmpfds内的子fd变化,发生变化的将会被保留在tmpfds中
          {
           perror("监视未成功");
            exit(-1);
         }
         
         for(fd1=0;fd1<FD_SETSIZE;fd1++)//循环找在最大范围内的fd1
        {
           if(FD_ISSET(fd1,&tmpfds))//查找是否fd1在tmpfds里面
            {
              if(fd1==listenfd)//判定fd1等于监听fd，即监听fd在监视过程中出现变化被发现
              {
                  addrlen=sizeof(cliaddr);
                 connfd=accept(listenfd,(struct sockaddr*)&cliaddr,&addrlen);//开始接收客户
                 FD_SET(connfd,&readfds);//将connfd加入监视集，监视接入的变化
                 printf("接入新的连接\n");
              }
              else
                  {
                      ioctl(fd1,FIONREAD,&nread);//测试在fd中还有nread个字符需要读取
                      if(nread==0)//如果需要读取的数据为0,则关闭检测出来的fd1，并且从监视中移除
                    {
                     close(fd1);
                     FD_CLR(fd1,&readfds);
                      printf("移除\n");
                    }
                      else//如果可读数据不为0，则读出来
                    {
                        int i;
                        char *p=NULL,*q=NULL;
                      n=read(fd1,buf,nread);
                      buf[n]=0;
                      p=buf;
                       
                       
                          if((strncmp(p,"-get",4)==0))
                          {  
                             q=p+5;
                             printf("客户下载文件>%s",q);
                             if((fd2=open(q,O_RDONLY))<0)
                                 perror("打开文件错误");
                             
                             while((m=read(fd2,buf,4096))>0)
                             {
                                 write(connfd,buf,m);
                                  
                             }
                             bzero(buf,sizeof(buf));
                             close(fd1);
                             close(fd2);
                             FD_CLR(fd1,&readfds);
                           
                          }
                           
                          if((strncmp(p,"-up",3)==0))
                          {  
                             q=p+4;
                             printf("客户上传文件%s\n",buf+4);
                             if((fd2=open(q,O_CREAT | O_WRONLY | O_APPEND ,0666))<0)
                             {
                                perror("打开文件写入失败");
                                  
                             }
                              
                             while((m=read(connfd,buf,128))>0)
                             { 
                                 printf("%s",buf);
                                 write(fd2,buf,m);
                             }
                             bzero(buf,sizeof(buf));
                             close(fd1);
                             close(fd2);
                             FD_CLR(fd1,&readfds);
                           
                          }
                           
                          if((strncmp(p,"-ls",3)==0))
                          {  
                             q=p+4;
                             printf("客户查看文件……");
                             if((dr=opendir(q))==NULL)
                                 perror("打开目录失败");
                             while((file=readdir(dr))!=NULL)
                             {
                                   printf("%s    ",file->d_name);
                                  write(connfd,file->d_name,sizeof(file->d_name));
 
                             }
                             close(fd1);
                             close(connfd);
                             closedir(dr);
                             FD_CLR(fd1,&readfds);
                           
                          }
                       
                      printf("从客户收取的信息:%s\n",buf);
                    }
 
 
                  }
 
            }//end if 0
             
          
        }//end for 0
 
     
    }//end while0
     
    exit(0);
}//end main




